import {
	HTTP_REQUEST_URL,
	HEADER
} from '@/config/app';
import API from "@/api/index.js"
import {
	toLogin,
	checkLogin
} from './login.js';
import {
	useUserStore
} from "@/store/index.js"
import {
	number
} from '../uni_modules/uview-plus/libs/function/test.js';
const userStore = useUserStore()

// 是否正在请求刷新token接口的标记
let isRefreshing = false;
// 请求队列
let requests = [];
/**
 * 发送请求
 */

function baseRequest(url, method, data, {
	noAuth = false,
	noVerify = false
}) {
	let Url = HTTP_REQUEST_URL,
		header = HEADER
	//需要有token的接口
	if (!noAuth) {
		//登录过期自动登录
		if (!userStore.token.tokenContent && !checkLogin()) {
			toLogin();
			return Promise.reject({
				msg: '未登录'
			});
		}
	}

	if (userStore.token.tokenContent) header['Authorization'] = 'Bearer ' + userStore.token.tokenContent;
	return new Promise(async (resolve, reject) => {

		uni.request({
			url: Url + '/api/' + url,
			method: method || 'GET',
			header: header,
			data: data || {},
			success: async (res) => {
				if (res.statusCode === 401) {
					// 返回401但无响应体 强制构造错误对象，触发 Token 刷新
					handleTokenExpired(url, method, data, {
						noAuth,
						noVerify
					}, resolve, reject);
					return;
				}
				switch (res.data.code) {
					case 1:
						resolve(res.data);
						break;
					case 2:
						// uni.showToast({
						// 	title: res.data.msg || '服务器错误'
						// })
						resolve(res.data);
						break;
					case 200:
						resolve(res.data.data);
						break;
					case 401:
						// Token 过期，加入队列等待刷新后重试
						if (!isRefreshing) {
							isRefreshing = true;
						} else {
							// 正在刷新，将当前请求加入队列
							return new Promise((retryResolve) => {
								requests.push(() => {
									baseRequest(url, method, data, {
										noAuth,
										noVerify
									}).then(retryResolve);
								});
							}).then(resolve);
						}
					default: {
						// ---------- 新增逻辑：无状态码但有数据 ----------
						// 检查是否存在有效数据字段（根据接口实际返回字段调整）
						if (res.data.tokenContent && res.data.expires) {
							// 即使无 code，但关键数据存在则视为成功
							resolve(res.data);
							break;
						} else {
							reject(res.data.msg || '服务器错误了');
							break;
						}
						// 无有效状态码且无有效数据，抛出错误
						// throw new Error(res.data.msg || '服务器返回数据异常');
					}
				}
			},
			fail: (error) => {
				if (error.statusCode === 401) {
					//  传递 resolve 和 reject
					handleTokenExpired(url, method, data, {
						noAuth,
						noVerify
					}, resolve, reject);
				} else {
					reject(error);
				}
			}
		})
	});
}

// 统一处理 Token 过期逻辑
const handleTokenExpired = async (url, method, data, options, resolve, reject) => {
	if (!isRefreshing) {
		isRefreshing = true;
		try {
			await handleRefreshToken();
			// 刷新后重新发起请求
			const retryRes = await baseRequest(url, method, data, options);
			resolve(retryRes);
			requests.forEach(cb => cb());
			requests = [];
		} catch (error) {
			requests = [];
			toLogin();
			reject(error);
		} finally {
			isRefreshing = false;
		}
	} else {
		// 加入队列等待刷新
		requests.push(() => {
			baseRequest(url, method, data, options)
				.then(resolve)
				.catch(reject);
		});
	}
};

const handleRefreshToken = async () => {
	try {
		const refreshToken = uni.getStorageSync('refreshToken').tokenContent;
		const res = await API.refreshCode({
			token: refreshToken
		});
		//  确保更新存储和状态管理
		uni.setStorageSync('accessToken', res);
		userStore.$patch((state) => {
			state.token = res;
		});
		console.log('Token 刷新成功:', res); // 调试日志
		return res;
	} catch (error) {
		console.error('Token 刷新失败:', error);
		throw error;
	}
};

// 判断 Token/refreshToken 是否即将过期
const isTokenExpired = (type) => {
	const tokenData = uni.getStorageSync(type);
	if (!tokenData || !tokenData.expires) return true;

	let expireTime = uni.getStorageSync(type).expires?.replace(" ", "T"); // 空格分隔可能会解析失败,兼容所有平台
	console.log(type + "是否即将过期", +new Date(), +new Date(expireTime), +new Date(expireTime) - 300000, +new Date() >=
		+new Date(expireTime));
	// 提前五分钟更新
	// return +new Date() >= +new Date(expireTime);
	return +new Date() >= +new Date(expireTime) - 300000;
};


const request = {};

['get', 'post', 'put', 'delete'].forEach((method) => {
	request[method] = (api, data, opt) => baseRequest(api, method, data, opt || {})
});


export default request;